package servlet;

import controller.ControllerAnnunciLocal;
import controller.ControllerIscrizioneAnnuncioLocal;
import controller.ControllerMail;
import eccezioni.AnnuncioChiusoException;
import eccezioni.CampoErratoException;
import entity.Adesione;
import entity.Annuncio;
import entity.Articolo;
import entity.UtenteRegistrato;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import statefulSB.UtenteLoggato;
import statefulSB.UtenteLoggato.StatoIscrizione;
import statefulSB.UtenteLoggatoLocal;
import utilities.Utilities;

/**
 * Servlet che fornisce le operazioni per l'iscrizione ad un annuncio e in
 * generale tutte le operazioni che permettono ad un iscritto di gestire
 * la propria adesione a un annuncio.
 * @author Ale
 */
public class IscrizioneAnnuncioServlet extends HttpServlet {

    @EJB
    private ControllerIscrizioneAnnuncioLocal controllerIscrizioneAnnuncio;
    @EJB
    private ControllerMail controllerMail;
    @EJB
    private ControllerAnnunciLocal controllerAnnunci;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getParameter("action");

        if (action == null) {
            Utilities.errore("Nessuna action specificata alla IscrizioneAnnuncioServlet", request, response);
        } else if (action.equals("mostraAggiungiArticoloPopup")) { //richiesta ajax
            mostraAggiungiArticoloPopup(request, response);
        } else if (action.equals("iscrivitiAnnuncio")) {
            iscrivitiAnnuncio(request, response);
        } else if (action.equals("modificaAdesioneAnnuncio")) {
            modificaAdesioneAnnuncio(request, response);
        } else if (action.equals("salvaAdesioneInCorso")) {
            salvaAdesioneInCorso(request, response);
        } else if (action.equals("annullaAdesioneInCorso")) {
            annullaAdesioneInCorso(request, response);
        } else if (action.equals("rimuoviArticolodaAdesioneTemporanea")) {
            rimuoviArticolodaAdesioneTemporanea(request, response);
        } else if (action.equals("aggiungiArticoloadAdesioneTemporanea")) {
            aggiungiArticoloadAdesioneTemporanea(request, response);
        } else if (action.equals("disiscriviDaAnnuncio")) {
            disiscriviDaAnnuncio(request, response);
        } else if (action.equals("checkIscrittoSito")) {
            checkIscrittoSito(request, response);
        }
    }

    private void mostraAggiungiArticoloPopup(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Long idAdesione = Long.parseLong(request.getParameter("adesione"));
        request.setAttribute("adesione", idAdesione);
        Utilities.forward("/WEB-INF/jspf/aggiungiArticolo.jsp", request, response);
    }

    private void iscrivitiAnnuncio(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("annuncio"));
        Annuncio a = controllerAnnunci.getAnnuncio(idAnnuncio);
        Adesione ad = a.isIscritto(Utilities.getUtenteLoggato(request));
        if (ad != null) {
            // l'utente è già iscritto all'annuncio
            request.setAttribute("errore", "Sei gi&agrave; iscritto all'annuncio per il sito " + a.getSito().getUrl() + " di " + a.getCreatoreAnnuncio().getNome() + " " + a.getCreatoreAnnuncio().getCognome() + ".");
            Utilities.mostraAnnunciIscritto(request, response, ad);
        } else {
            // creo l'adesione e la salvo nel session bean. Non la rendo ancora persistente
            ad = new Adesione();
            ad.setAnnuncio(a);
            ad.setIscritto(Utilities.getUtenteLoggato(request));
            ad.setArticoli(new LinkedList<Articolo>());
            ad.setLasciatoFeedbackPerCreatore(false);
            ad.setLasciatoFeedbackPerIscritto(false);
            ad.setPagata(false);
            ad.setStato(Adesione.StatoAdesione.IN_SOSPESO);

            UtenteLoggatoLocal utenteLoggato = Utilities.getUtenteLoggatoLocal(request);
            utenteLoggato.setStatoIscrizione(StatoIscrizione.ISCRIZIONE);
            utenteLoggato.aggiungiAdAdesioni(ad);

            // le adesioni sono identificate dall'annuncio a cui si riferiscono, finché non sono salvate su db
            request.setAttribute("annuncio", a);
            Utilities.forward("/iscrizioneAnnuncio.jsp", request, response);
        }
    }

    private void modificaAdesioneAnnuncio(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAdesione = Long.parseLong(request.getParameter("adesione"));
        Adesione ad = controllerAnnunci.getAdesione(idAdesione);

        // riporto l'adesione nel session bean.
        UtenteLoggatoLocal utenteLoggato = Utilities.getUtenteLoggatoLocal(request);
        utenteLoggato.setStatoIscrizione(StatoIscrizione.MODIFICA);
        utenteLoggato.aggiungiAdAdesioni(ad);

        // le adesioni sono identificate dall'annuncio a cui si riferiscono, finché non sono salvate su db
        request.setAttribute("annuncio", ad.getAnnuncio());
        Utilities.forward("/iscrizioneAnnuncio.jsp", request, response);
    }

    private void salvaAdesioneInCorso(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        UtenteLoggatoLocal utenteLoggato = Utilities.getUtenteLoggatoLocal(request);

        Adesione ad = utenteLoggato.getAdesioneByAnnuncioId(idAnnuncio);

        if (ad.getArticoli().isEmpty()) {
            request.setAttribute("annuncio", ad.getAnnuncio());
            request.setAttribute("errore", "<li>La tua adesione deve contenere almeno un articolo.</li>");
            Utilities.forward("/iscrizioneAnnuncio.jsp", request, response);
        } else {
            controllerIscrizioneAnnuncio.salvaAdesioneTemporanea(ad);
            // rimuovo l'adesione dalla lista di adesioni temporanee
            utenteLoggato.annullaAdesione(idAnnuncio);

            // notifica al creatore
            UtenteRegistrato creatore = ad.getAnnuncio().getCreatoreAnnuncio();

            if (utenteLoggato.getStatoIscrizione() == UtenteLoggato.StatoIscrizione.ISCRIZIONE) {
                controllerMail.sendMailNuovaIscrizione(Utilities.getUtenteLoggato(request), creatore, ad);
            } else {
                controllerMail.sendMailIscrizioneModificata(Utilities.getUtenteLoggato(request), creatore, ad);
            }

            utenteLoggato.setStatoIscrizione(StatoIscrizione.NESSUNO);

            Utilities.mostraAnnunciIscritto(request, response, ad);
        }
    }

    private void annullaAdesioneInCorso(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        UtenteLoggatoLocal utenteLoggato = Utilities.getUtenteLoggatoLocal(request);

        utenteLoggato.annullaAdesione(idAnnuncio);

        Utilities.forward("/index.jsp", request, response);
    }

    private void rimuoviArticolodaAdesioneTemporanea(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        String url = request.getParameter("urlArticolo");
        UtenteLoggatoLocal utenteLoggato = Utilities.getUtenteLoggatoLocal(request);
        List<Articolo> articoli = utenteLoggato.getAdesioneByAnnuncioId(idAnnuncio).getArticoli();

        int index = 0;

        for (int i = 0; i < articoli.size(); i++) {
            Articolo art = articoli.get(i);
            if (url.equals(art.getUrl())) {
                index = i;
                i = articoli.size(); // esco dal ciclo
            }
        }

        articoli.remove(index);

        request.setAttribute("annuncio", controllerAnnunci.getAnnuncio(idAnnuncio));
        Utilities.forward("/iscrizioneAnnuncio.jsp", request, response);
    }

    private void aggiungiArticoloadAdesioneTemporanea(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        String url = request.getParameter("urlArticolo");
        String prezzoStr = request.getParameter("prezzo");
        String note = request.getParameter("note");

        Articolo art;
        try {
            art = controllerIscrizioneAnnuncio.creaArticolo(url, prezzoStr, note);

            UtenteLoggatoLocal utenteLoggato = Utilities.getUtenteLoggatoLocal(request);
            if (utenteLoggato != null) {
                utenteLoggato.aggiungiArticoloAdAdesione(idAnnuncio, art);
                request.setAttribute("annuncio", controllerAnnunci.getAnnuncio(idAnnuncio));
                Utilities.forward("/iscrizioneAnnuncio.jsp", request, response);
            } else {
                Utilities.errore("Devi essere loggato per aggiungere articoli alla tua adesione.", request, response);
            }

        } catch (CampoErratoException ex) {
            request.setAttribute("annuncio", controllerAnnunci.getAnnuncio(idAnnuncio));
            request.setAttribute("errore", ex.getMessage());
            Utilities.forward("/iscrizioneAnnuncio.jsp", request, response);
        }


    }

    private void disiscriviDaAnnuncio(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long idAdesione = Long.parseLong(request.getParameter("idAdesione"));
        Adesione ad = controllerAnnunci.getAdesione(idAdesione);
        try {
            controllerIscrizioneAnnuncio.disiscriviDaAnnuncio(ad);
            controllerMail.sendMailUtenteDisiscritto(ad.getIscritto(), ad.getAnnuncio().getCreatoreAnnuncio(), ad);
            Utilities.mostraAnnunciIscritto(request, response, null);
        } catch (AnnuncioChiusoException ace) {
            Utilities.errore(ace.getMessage(), request, response);
        }
    }

    private void checkIscrittoSito(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }

        String sito = request.getParameter("url");
        long idAnnuncio = Long.parseLong(request.getParameter("idAnnuncio"));
        Annuncio a = controllerAnnunci.getAnnuncio(idAnnuncio);

        List<Adesione> adesioni = controllerIscrizioneAnnuncio.checkIscrittoSito(Utilities.getUtenteLoggato(request), sito);
        if (adesioni.isEmpty()) {
            out.print("");
            return;
        } else {
            request.setAttribute("url", sito);
            request.setAttribute("adesioni", adesioni);
            request.setAttribute("annuncio", a);
            Utilities.forward("/WEB-INF/jspf/giaIscritto.jsp", request, response);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
    
}
